package com.sagframe.sagacity.sqltoy.plus.multi;

import com.sagframe.sagacity.sqltoy.plus.MultiFiledMappingStrategy;
import com.sagframe.sagacity.sqltoy.plus.conditions.ISqlSegment;
import com.sagframe.sagacity.sqltoy.plus.conditions.eumn.CompareEnum;
import com.sagframe.sagacity.sqltoy.plus.conditions.eumn.SqlKeyword;
import com.sagframe.sagacity.sqltoy.plus.conditions.interfaces.SFunction;
import com.sagframe.sagacity.sqltoy.plus.FiledValueFilterStrategy;
import com.sagframe.sagacity.sqltoy.plus.conditions.segments.SqlSegmentMeta;
import com.sagframe.sagacity.sqltoy.plus.conditions.toolkit.LambdaUtils;
import com.sagframe.sagacity.sqltoy.plus.conditions.toolkit.FiledNature;
import com.sagframe.sagacity.sqltoy.plus.conditions.toolkit.StringPool;
import com.sagframe.sagacity.sqltoy.plus.multi.interfaces.LambdaCondition;
import org.sagacity.sqltoy.utils.StringUtil;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public abstract class AbstractLambdaMultiWrapper<Children extends AbstractLambdaMultiWrapper<Children>> extends AbstractMultiWrapper<Children> implements LambdaCondition<Children>{

    public AbstractLambdaMultiWrapper(Class<?> toClass) {
        super(toClass);
        context.addSqlAssembler(mappingStrategy -> {
            ISqlSegment sqlSegment = typedThis.getISqlSegment(mappingStrategy);
            if (sqlSegment != null) {
                String conditionSql = sqlSegment.getSqlSegment();
                if (conditionSql != null && !conditionSql.isEmpty()) {
                    context.addConditionSqlSegment(new ISqlSegment() {
                        @Override
                        public String getSqlSegment() {
                            return conditionSql;
                        }
                        public Map<String, Object> getSqlSegmentParamMap() {
                            return sqlSegment.getSqlSegmentParamMap();
                        }
                    });
                }
            }
        });
    }

    public AbstractLambdaMultiWrapper(MultiContext context) {
        super(context);
    }

    /**
     * 子类返回一个自己的新对象
     * @return
     *              -返回自身
     */
    protected abstract LambdaCondition<Children> instance();

    /**
     * 普通查询条件
     *
     * @param condition  是否执行
     * @param column     属性
     * @param compareEnum SQL 关键词
     * @param val        条件值
     */
    private  <T> Children addNeedValCondition(MultiFiledMappingStrategy mappingStrategy, boolean condition, SFunction<T, ?> column, CompareEnum compareEnum, Object val) {
        return maybeDo(condition, () -> addSqlSegment(mappingStrategy, column, compareEnum, val));
    }

    /**
     * 设置查询条件封装的单元对象
     * @param column
     * @param compareEnum
     * @param val
     */
    private <T> void addSqlSegment(MultiFiledMappingStrategy mappingStrategy, SFunction<T, ?> column, CompareEnum compareEnum, Object val) {
        boolean isAllow = FiledValueFilterStrategy.FiledValueFilterStrategyHolder.getInstance().validate(val);
        if (isAllow) {
            FiledNature nature = LambdaUtils.extractToNature(column);
            final String paramName = context.getParamName(nature.getFiledName());
            String columnName = mappingStrategy.getColumnName(context, nature.getClazz(), nature.getFiledName());
            SqlSegmentMeta sqlSegmentMeta = new SqlSegmentMeta();
            sqlSegmentMeta.setCompareEnum(compareEnum);
            sqlSegmentMeta.setEntityFiledName(nature.getFiledName());
            sqlSegmentMeta.setParamName(paramName);
            sqlSegmentMeta.setColumnName(columnName);
            sqlSegmentMeta.putPair(paramName, val);
            appendSqlSegments(sqlSegmentMeta);
        }
    }

    /**
     * 获取属性名称
     * @param column
     *             -抽象的属性定义
     * @return
     *             -返回自身
     */
    private <T> String columnToString(MultiFiledMappingStrategy mappingStrategy, SFunction<T, ?> column) {
        FiledNature nature = LambdaUtils.extractToNature(column);
        return mappingStrategy.getColumnName(context, nature.getClazz(), nature.getFiledName());
    }

    private <T> void addBatchInCondition(MultiFiledMappingStrategy mappingStrategy, boolean condition, Collection<SFunction<T, ?>> columns, Collection<Object[]> values) {
        List<FiledNature> natures = columns.stream().map(LambdaUtils::extractToNature).collect(Collectors.toList());
        List<String> columnNames = new ArrayList<>();
        List<String> paramNames = new ArrayList<>();
        Map<String, Object> paramMap = new HashMap<>();
        for (int i = 0; i < natures.size(); i++) {
            FiledNature nature = natures.get(i);
            columnNames.add(mappingStrategy.getColumnName(context, nature.getClazz(), nature.getFiledName()));
            String paramName = context.getParamName(nature.getFiledName());
            paramNames.add(paramName);
            int finalI = i;
            paramMap.put(paramName, values.stream().map(e -> e[finalI]).collect(Collectors.toList()));
        }
        maybeDo(condition, () -> appendSqlSegments(new ISqlSegment() {
            @Override
            public String getSqlSegment() {
                return CompareEnum.IN_BATCH.getBatchMetaSql(paramNames, columnNames);
            }
            @Override
            public Map<String, Object> getSqlSegmentParamMap() {
                return paramMap;
            }
        }));
    }

    /**
     * 等于 =
     *
     * @param condition 执行条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    @Override
    public <T> Children eq(boolean condition, SFunction<T, ?> column, Object val) {
        if (!validateFiledValue(val)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.EQ, val));
    }

    /**
     * 不等于 &lt;&gt;
     *
     * @param condition 执行条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    @Override
    public <T> Children ne(boolean condition, SFunction<T, ?> column, Object val) {
        if (!validateFiledValue(val)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.NE, val));
    }

    /**
     * 大于 &gt;
     *
     * @param condition 执行条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    @Override
    public <T> Children gt(boolean condition, SFunction<T, ?> column, Object val) {
        if (!validateFiledValue(val)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.GT, val));
    }

    /**
     * 大于等于 &gt;=
     *
     * @param condition 执行条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    @Override
    public <T> Children ge(boolean condition, SFunction<T, ?> column, Object val) {
        if (!validateFiledValue(val)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.GE, val));
    }

    /**
     * 小于 &lt;
     *
     * @param condition 执行条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    @Override
    public <T> Children lt(boolean condition, SFunction<T, ?> column, Object val) {
        if (!validateFiledValue(val)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.LT, val));
    }

    /**
     * 小于等于 &lt;=
     *
     * @param condition 执行条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    @Override
    public <T> Children le(boolean condition, SFunction<T, ?> column, Object val) {
        if (!validateFiledValue(val)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.LE, val));
    }

    /**
     * BETWEEN 值1 AND 值2
     *
     * @param condition 执行条件
     * @param column    字段
     * @param val1      值1
     * @param val2      值2
     * @return children
     */
    @Override
    public <T> Children between(boolean condition, SFunction<T, ?> column, Object val1, Object val2) {
        if (!validateFiledValue(val1) || !validateFiledValue(val2)) {
            return typedThis;
        }
        return addAssembler((strategy) -> {
            maybeDo(condition, () -> {
                FiledNature nature = LambdaUtils.extractToNature(column);
                String val1Name = context.getParamName(nature.getFiledName());
                String val2Name = context.getParamName(nature.getFiledName());
                appendSqlSegments(new ISqlSegment() {
                    @Override
                    public String getSqlSegment() {
                        return CompareEnum.BETWEEN.getMetaSql(strategy.getColumnName(context, nature.getClazz(), nature.getFiledName()), val1Name, val2Name);
                    }
                    @Override
                    public Map<String, Object> getSqlSegmentParamMap() {
                        HashMap<String, Object> map = new HashMap<>();
                        map.put(val1Name, val1);
                        map.put(val2Name, val2);
                        return map;
                    }
                });
            });
        });
    }

    /**
     * NOT BETWEEN 值1 AND 值2
     *
     * @param condition 执行条件
     * @param column    字段
     * @param val1      值1
     * @param val2      值2
     * @return children
     */
    @Override
    public <T> Children notBetween(boolean condition, SFunction<T, ?> column, Object val1, Object val2) {
        if (!validateFiledValue(val1) || !validateFiledValue(val2)) {
            return typedThis;
        }
        return addAssembler((strategy) -> {
            maybeDo(condition, () -> {
                FiledNature nature = LambdaUtils.extractToNature(column);
                String val1Name = context.getParamName(nature.getFiledName());
                String val2Name = context.getParamName(nature.getFiledName());
                appendSqlSegments(new ISqlSegment() {
                    @Override
                    public String getSqlSegment() {
                        return CompareEnum.NOT_BETWEEN.getMetaSql(strategy.getColumnName(context, nature.getClazz(), nature.getFiledName()), val1Name, val2Name);
                    }
                    @Override
                    public Map<String, Object> getSqlSegmentParamMap() {
                        HashMap<String, Object> map = new HashMap<>();
                        map.put(val1Name, val1);
                        map.put(val2Name, val2);
                        return map;
                    }
                });
            });
        });
    }

    /**
     * LIKE '%值%'
     *
     * @param condition 执行条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    @Override
    public <T> Children like(boolean condition, SFunction<T, ?> column, Object val) {
        if (!validateFiledValue(val)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.LIKE, val));
    }

    /**
     * NOT LIKE '%值%'
     *
     * @param condition 执行条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    @Override
    public <T> Children notLike(boolean condition, SFunction<T, ?> column, Object val) {
        if (!validateFiledValue(val)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.NOT_LIKE, val));
    }

    /**
     * LIKE '%值'
     *
     * @param condition 执行条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    @Override
    public <T> Children likeLeft(boolean condition, SFunction<T, ?> column, Object val) {
        if (!validateFiledValue(val)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.LIKE_LEFT, val));
    }

    /**
     * LIKE '值%'
     *
     * @param condition 执行条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    @Override
    public <T> Children likeRight(boolean condition, SFunction<T, ?> column, Object val) {
        if (!validateFiledValue(val)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.LIKE_RIGHT, val));
    }

    /**
     * 字段 IS NULL
     * <p>例: isNull("name")</p>
     *
     * @param condition 执行条件
     * @param column    字段
     * @return children
     */
    @Override
    public <T> Children isNull(boolean condition, SFunction<T, ?> column) {
        return addAssembler((strategy) -> maybeDo(condition, () -> {
            appendSqlSegments(() -> CompareEnum.IS_NULL.getMetaSql(columnToString(strategy, column)));
        }));
    }

    /**
     * 字段 IS NOT NULL
     * <p>例: isNotNull("name")</p>
     *
     * @param condition 执行条件
     * @param column    字段
     * @return children
     */
    @Override
    public <T> Children isNotNull(boolean condition, SFunction<T, ?> column) {
        return addAssembler((strategy) -> maybeDo(condition, () -> {
            appendSqlSegments(() -> CompareEnum.IS_NOT_NULL.getMetaSql(columnToString(strategy, column)));
        }));
    }

    /**
     * 字段 IN (value.get(0), value.get(1), ...)
     * <p>例: in("id", Arrays.asList(1, 2, 3, 4, 5))</p>
     *
     * <li> 注意！集合为空若存在逻辑错误，请在 condition 条件中判断 </li>
     * <li> 如果集合为 empty 则不会进行 sql 拼接 </li>
     *
     * @param condition 执行条件
     * @param column    字段
     * @param coll      数据集合
     * @return children
     */
    @Override
    public <T> Children in(boolean condition, SFunction<T, ?> column, Collection<?> coll) {
        if (!validateFiledValue(coll)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.IN, coll));
    }

    /**
     * 字段 IN (v0, v1, ...)
     * <p>例: in("id", 1, 2, 3, 4, 5)</p>
     *
     * <li> 注意！数组为空若存在逻辑错误，请在 condition 条件中判断 </li>
     * <li> 如果动态数组为 empty 则不会进行 sql 拼接 </li>
     *
     * @param condition 执行条件
     * @param column    字段
     * @param values    数据数组
     * @return children
     */
    @Override
    public <T> Children in(boolean condition, SFunction<T, ?> column, Object... values) {
        if (!validateFiledValue(values)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.IN, values));
    }

    @Override
    public <T> LambdaCondition<Children> inSql(boolean condition, SFunction<T, ?> column, String sql, Map<String, Object> paramMap) {
        if (sql == null || sql.isEmpty()) {
            return typedThis;
        }
        return addAssembler((strategy) -> {
            maybeDo(condition, () -> {
                FiledNature nature = LambdaUtils.extractToNature(column);
                appendSqlSegments(new ISqlSegment() {
                    @Override
                    public String getSqlSegment() {
                        return CompareEnum.IN_INNER_SQL.getMetaSql(strategy.getColumnName(context, nature.getClazz(), nature.getFiledName()), sql);
                    }
                    @Override
                    public Map<String, Object> getSqlSegmentParamMap() {
                        return paramMap;
                    }
                });
            });
        });
    }

    /**
     * (字段1,字段2...) IN ((v0, v1...), (v2, v3...)...)
     * <p>例: in("id","code", Object[]...)</p>
     *
     * <li> 注意！数组为空若存在逻辑错误，请在 condition 条件中判断 </li>
     * <li> 如果动态数组为 empty 则不会进行 sql 拼接 </li>
     *
     * @param condition 执行条件
     * @param columns   字段集合
     * @param values    数据数组
     * @return children
     */
    @Override
    public <T> Children inb(boolean condition, Collection<SFunction<T, ?>> columns, Collection<Object[]> values) {
        if (columns == null || columns.size() == 0 || values == null || values.size() == 0) {
            return typedThis;
        }
        return addAssembler((strategy) -> addBatchInCondition(strategy, condition, columns, values));
    }

    /**
     * 字段 NOT IN (value.get(0), value.get(1), ...)
     * <p>例: notIn("id", Arrays.asList(1, 2, 3, 4, 5))</p>
     *
     * @param condition 执行条件
     * @param column    字段
     * @param coll      数据集合
     * @return children
     */
    @Override
    public <T> Children notIn(boolean condition, SFunction<T, ?> column, Collection<?> coll) {
        if (!validateFiledValue(coll)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.NOT_IN, coll));
    }

    /**
     * 字段 NOT IN (v0, v1, ...)
     * <p>例: notIn("id", 1, 2, 3, 4, 5)</p>
     *
     * @param condition 执行条件
     * @param column    字段
     * @param values    数据数组
     * @return children
     */
    @Override
    public <T> Children notIn(boolean condition, SFunction<T, ?> column, Object... values) {
        if (!validateFiledValue(values)) {
            return typedThis;
        }
        return addAssembler((strategy) -> addNeedValCondition(strategy, condition, column, CompareEnum.NOT_IN, values));
    }

    /**
     * 分组：GROUP BY 字段, ...
     * <p>例: groupBy("id")</p>
     *
     * @param condition 执行条件
     * @param column    单个字段
     * @return children
     */
    @Override
    public <T> Children groupBy(boolean condition, SFunction<T, ?> column) {
        return addAssembler((strategy) -> {
            maybeDo(condition, () -> appendSqlSegments(SqlKeyword.GROUP_BY, () -> columnToString(strategy, column)));
        });
    }

    /**
     * 分组：GROUP BY 字段, ...
     * <p>例: groupBy(Arrays.asList("id", "name"))</p>
     *
     * @param condition 执行条件
     * @param columns   字段数组
     * @return children
     */
    @Override
    public <T> Children groupBy(boolean condition, List<SFunction<T, ?>> columns) {
        return addAssembler((strategy) -> {
            List<FiledNature> natures = columns.stream().map(LambdaUtils::extractToNature).collect(Collectors.toList());
            maybeDo(condition, () -> appendSqlSegments(SqlKeyword.GROUP_BY, () -> strategy.getSplitColumnName(context, natures, StringPool.COMMA)));
        });
    }

    /**
     * 分组：GROUP BY 字段, ...
     *
     * @param condition
     * @param column
     * @param columns
     */
    @Override
    public <T> Children groupBy(boolean condition, SFunction<T, ?> column, SFunction<T, ?>... columns) {
        List<SFunction<T, ?>> list = new ArrayList<>();
        if (column != null) {
            list.add(column);
        }
        if (columns != null && columns.length > 0) {
            list.addAll(Arrays.asList(columns));
        }
        return groupBy(condition, list);
    }

    /**
     * 排序：ORDER BY 字段, ...
     * <p>例: orderBy(true, "id")</p>
     *
     * @param condition 执行条件
     * @param isAsc     是否是 ASC 排序
     * @param column    单个字段
     * @return children
     */
    @Override
    public <T> Children orderBy(boolean condition, boolean isAsc, SFunction<T, ?> column) {
        return addAssembler((strategy) -> {
            maybeDo(condition, () -> appendSqlSegments(SqlKeyword.ORDER_BY, () -> columnToString(strategy, column),
                    isAsc ? SqlKeyword.ASC : SqlKeyword.DESC));
        });
    }

    /**
     * 排序：ORDER BY 字段, ...
     * <p>例: orderBy(true, Arrays.asList("id", "name"))</p>
     *
     * @param condition 执行条件
     * @param isAsc     是否是 ASC 排序
     * @param columns   字段列表
     * @return children
     */
    @Override
    public <T> Children orderBy(boolean condition, boolean isAsc, List<SFunction<T, ?>> columns) {
        return addAssembler((strategy) -> {
            maybeDo(condition, () -> {
                List<FiledNature> natures = columns.stream().map(LambdaUtils::extractToNature).collect(Collectors.toList());
                natures.forEach(c -> appendSqlSegments(SqlKeyword.ORDER_BY, () -> strategy.getColumnName(context, c.getClazz(), c.getFiledName()), isAsc ? SqlKeyword.ASC : SqlKeyword.DESC));
            });
        });
    }


    /**
     * 排序：ORDER BY 字段, ...
     *
     * @param condition
     * @param isAsc
     * @param column
     * @param columns
     */
    @Override
    public <T> Children orderBy(boolean condition, boolean isAsc, SFunction<T, ?> column, SFunction<T, ?>... columns) {
        return addAssembler((strategy) -> {
            final SqlKeyword mode = isAsc ? SqlKeyword.ASC : SqlKeyword.DESC;
            appendSqlSegments(SqlKeyword.ORDER_BY, () -> columnToString(strategy, column), mode);
            if (columns != null && columns.length > 0) {
                Arrays.stream(columns).forEach(c -> appendSqlSegments(SqlKeyword.ORDER_BY,
                        () -> columnToString(strategy, c), mode));
            }
        });
    }

    /**
     * HAVING ( sql语句 )
     * <p>例1: having("sum(age) &gt; 10")</p>
     * <p>例2: having("sum(age) &gt; {0}", 10)</p>
     *
     * @param condition 执行条件
     * @param sqlHaving sql 语句
     * @param paramMap  参数数据
     * @return children
     */
    @Override
    public <T> Children having(boolean condition, String sqlHaving, Map<String, Object> paramMap) {
        if (!validateFiledValue(paramMap)) {
            return typedThis;
        }
        return addAssembler((strategy) -> {
            maybeDo(condition, () -> appendSqlSegments(SqlKeyword.HAVING, new ISqlSegment() {
                @Override
                public String getSqlSegment() {
                    return sqlHaving;
                }
                @Override
                public Map<String, Object> getSqlSegmentParamMap() {
                    return paramMap;
                }
            }));
        });
    }

    /**
     * 拼接 OR
     *
     * @param condition 执行条件
     * @return children
     */
    @Override
    public Children or(boolean condition) {
        return addAssembler((strategy) -> {
            maybeDo(condition, () -> appendSqlSegments(SqlKeyword.OR));
        });
    }

    /**
     * 拼接 and
     *
     * @param condition 执行条件
     * @return children
     */
    @Override
    public Children and(boolean condition) {
        return addAssembler((strategy) -> {
            maybeDo(condition, () -> appendSqlSegments(SqlKeyword.AND));
        });
    }

    /**
     * 无视优化规则直接拼接到 sql 的最后(有sql注入的风险,请谨慎使用)
     * <p>例: last("limit 1")</p>
     * <p>注意只能调用一次,多次调用以最后一次为准</p>
     *
     * @param condition 执行条件
     * @param lastSql   sql语句
     * @return children
     */
    @Override
    public Children last(boolean condition, String lastSql) {
        return addAssembler((strategy) -> {
            maybeDo(condition, () -> setLastSql(lastSql));
        });
    }

    /**
     * AND 嵌套
     * <p>
     * 例: and(i -&gt; i.eq("name", "李白").ne("status", "活着"))
     * </p>
     *
     * @param condition 执行条件
     * @param function  消费函数
     * @return children
     */
    @Override
    public Children and(boolean condition, Function<LambdaCondition<Children>, LambdaCondition<Children>> function) {
        return and(condition).addAssembler((strategy) -> {
            addNestedCondition(strategy,condition, function);
        });
    }

    /**
     * OR 嵌套
     * <p>
     * 例: or(i -&gt; i.eq("name", "李白").ne("status", "活着"))
     * </p>
     *
     * @param condition 执行条件
     * @param function  消费函数
     * @return children
     */
    @Override
    public Children or(boolean condition, Function<LambdaCondition<Children>, LambdaCondition<Children>> function) {
        return or(condition).addAssembler((strategy) -> {
            addNestedCondition(strategy,condition, function);
        });
    }

    /**
     * 正常嵌套 不带 AND 或者 OR
     * <p>
     * 例: nested(i -&gt; i.eq("name", "李白").ne("status", "活着"))
     * </p>
     *
     * @param condition 执行条件
     * @param function  消费函数
     * @return children
     */
    @Override
    public Children nested(boolean condition, Function<LambdaCondition<Children>, LambdaCondition<Children>> function) {
        return addAssembler((strategy) -> {
            addNestedCondition(strategy,condition, function);
        });
    }

    /**
     * not嵌套
     * <p>
     * 例: not(i -&gt; i.eq("name", "李白").ne("status", "活着"))
     * </p>
     *
     * @param condition 执行条件
     * @param function  消费函数
     * @return children
     */
    @Override
    public Children not(boolean condition, Function<LambdaCondition<Children>, LambdaCondition<Children>> function) {
        return not(condition).addAssembler((strategy) -> {
            addNestedCondition(strategy,condition, function);
        });
    }

    /**
     * 获取condition的sql片段对象
     * @param mappingStrategy
     * @return
     */
    public ISqlSegment getISqlSegment(MultiFiledMappingStrategy mappingStrategy) {
        return super.getISqlSegment(mappingStrategy);
    }

    /**
     * 多重嵌套查询条件
     *
     * @param condition 查询条件值
     */
    private Children addNestedCondition(MultiFiledMappingStrategy mappingStrategy, boolean condition, Function<LambdaCondition<Children>, LambdaCondition<Children>> function) {
        return maybeDo(condition, () -> {
            final LambdaCondition<Children> instance = instance();
            LambdaCondition<Children> nested = function.apply(instance);
            ISqlSegment sqlSegment = nested.getISqlSegment(mappingStrategy);
            if (sqlSegment != null) {
                String sql = sqlSegment.getSqlSegment();
                if (StringUtil.isNotBlank(sql)) {
                    appendSqlSegments(new ISqlSegment() {
                        @Override
                        public String getSqlSegment() {
                            return StringPool.LEFT_BRACKET + sql + StringPool.RIGHT_BRACKET;
                        }

                        @Override
                        public Map<String, Object> getSqlSegmentParamMap() {
                            return sqlSegment.getSqlSegmentParamMap();
                        }
                    });
                }
            }
        });
    }
}
